<template>
  <div class="my_page_container">
    <q-splitter
      class="bg-white"
      v-model="splitterRatio"
      style="height: 550px"
    >
      <template v-slot:before>
        <div class="row q-pa-xs q-gutter-sm">
            <q-input outlined dense color="base" style="width: 130px">
              <template v-slot:append>
                <q-icon name="search" color="indigo" />
              </template>
            </q-input>
            <q-btn
              dense
              outline
              color="primary"
              label="刷新"
              icon="refresh"
            />
          </div>
        <q-separator />
        <q-scroll-area class="my-scroll-area">
          <div class="q-ma-md my-text-overflow">
            <q-tree
            icon="mdi-key"
            ref="myNavTreeRef"
            :nodes="uTreeList"
            node-key="sid"
            label-key="name"
            selected-color="primary"
            v-model:selected="myNavTreeSelectedItem"
            @update:selected="onNavTreeSelected"
          />
        </div>
        </q-scroll-area>
      </template>

      <template v-slot:after>
        <div class="bg-white">
          <AmyQueryItem
            search-label="用户账号"
            @make-search-condition="queryTable"
          />
        </div>
        <div class="bg-white">
          <q-table
            id="my-xls"
            bordered
            flat
            separator="cell"
            :tableTitle= "tableTitle"
            :columns="columns"
            row-key="name"
            :rows="dbFilterList"
            :dbPagination="dbPagination"
            :rows-per-page-options="[10,20]"
            selection="multiple"
            v-model:selected="selectedItems"
          >

            <!--  插槽：表格头部左侧    -->
            <template v-slot:top-left>
              <q-input outlined dense color="base" v-model="filterText" :input-style="{ width: '150px'}">
                <template v-slot:append>
                  <q-icon name="search" color="indigo" @click="searchTableAry"/>
                </template>
              </q-input>
            </template>

            <!--  插槽：表格头部左侧    -->
            <template v-slot:top-right>
              <div class="q-gutter-sm">
                <q-btn
                  dense
                  unelevated
                  color="secondary"
                  label="新增"
                  icon="mdi-comment-plus"
                  @click="addDlgItem"
                />
                <q-btn
                  dense
                  unelevated
                  color="amber"
                  label="导入"
                  icon="mdi-file-import"
                />
                <q-btn
                  dense
                  unelevated
                  color="pink"
                  label="导出"
                  icon="mdi-database-export"
                  @click="exportExcel"
                />
              </div>
            </template>

            <!--  插槽：某个单元格    -->
            <template #body-cell-roleId="props">
              <q-td :props="props">
                {{findCatalogLabel(roleList, props.row.roleId)}}
              </q-td>
            </template>
            <template #body-cell-userStatusId="props">
              <q-td :props="props">
                <q-badge
                  outline
                  color="deep-orange"
                  :label="findCatalogLabel(statusTypeList, props.row.userStatusId)"
                />
              </q-td>
            </template>
            <template #body-cell-operation="props">
              <q-td :props="props">
                <q-btn flat round dense color="primary" icon="mdi-key">
                  <q-tooltip>重置密码</q-tooltip>
                </q-btn>
                <q-btn
                  flat
                  round
                  dense
                  color="primary"
                  icon="engineering"
                  @click="assignRole(props.row.id, props.row.nick, props.row.roleId)"
                >
                  <q-tooltip>分配角色</q-tooltip>
                </q-btn>
                <q-btn
                  flat
                  round
                  dense
                  color="primary"
                  icon="edit"
                  @click="editDlgItem(props.rowIndex)">
                  <q-tooltip>编辑</q-tooltip>
                </q-btn>
                <q-btn
                  flat
                  round
                  dense
                  color="negative"
                  icon="mdi-delete-empty"
                  @click="deleteDlgItem(props.rowIndex)">
                  <q-tooltip>删除</q-tooltip>
                </q-btn>
              </q-td>
            </template>
            <!--   底部插槽     -->
            <template v-slot:bottom>
              <AmyPagination :page-msg="dbPagination" @update="refreshTableAry"/>
            </template>
          </q-table>
          <UserDlg
            ref="myAddDlgRef"
            :itemData = "getActiveItem()"
            :sexTypeArr = "sexTypeList"
            :positionTypeArr="positionTypeList"
            :departmentTypeArr="departmentTypeList"
            :statusTypeArr="statusTypeList"
            :roleArr="roleList"
            :companyArr="companyList"
            @cancel-user-item="cancelAddDlg"
            @submit-user-item="submitAddDlg"
          />
          <AmyDeleteDlg
            ref="myDelDlgRef"
            :selected-index="deletedIndex"
            @btnSubmit="submitDelDlg"
          />
        </div>
        <UserSetRoleDlg
          ref="myRoleRef"
          :item-data="RoleItem"
          :role-arr="roleList"
          @cancel-role-item="cancelAssignRoleDlg"
          @submit-role-item="submitAssignRoleDlg"
        />
      </template>
    </q-splitter>
  </div>
</template>

<script lang="ts">
import { defineAsyncComponent, defineComponent, onMounted, onUnmounted, reactive, ref, watch } from 'vue';
import { useSysCatalogTbl } from '../../../hook/useSysCatalogTbl';
import { sysCatalogType, sysBaseVOAPI, sysBaseUrlAPI } from '../../../util/SysBaseConst';
import api from 'axios';
import * as XLSX from 'xlsx';
import { useMessageNotify } from 'src/hook/common/useMessageNotify';
import BaseItem from 'pages/BaseItem.vue';
import { EStatusType, ItemType } from 'src/hook/common/useCommonVisitType';
import useCommonVisitDatabase from 'src/hook/common/useCommonVisitDatabase';
import { useCatalogTool } from 'src/hook/common/useCatalogTool';
import { CQueryParam } from 'src/components/basic/basicModel';

import { UserItem, UserNodeVO } from './UserModel';
import { useCommonTree } from 'src/hook/common/useCommonTree';

const AmyDeleteDlg = defineAsyncComponent(() => import('components/basic/AmyDeleteDlg.vue'));
const UserDlg = defineAsyncComponent(() => import('./UserDlg.vue'));
const UserSetRoleDlg = defineAsyncComponent(() => import('./UserSetRoleDlg.vue'));
export type UserDlgInstance = InstanceType<typeof UserDlg>;
export type UserSetRoleDlgInstance = InstanceType<typeof UserSetRoleDlg>;
export type DeleteDlgInstance = InstanceType<typeof AmyDeleteDlg>;

export default defineComponent({
  name: 'UserIndex',
  extends: BaseItem,
  components: {
    UserDlg,
    UserSetRoleDlg
  },

  setup (props, context) {
    //*********************************************************************************************
    //      splitter
    //*********************************************************************************************
    //分割组件分割比例30%
    let splitterRatio = ref(20);

    //*********************************************************************************************
    //      消息通知
    //*********************************************************************************************
    //消息通知
    const {
      showSuccessMessage,
      showMessage
    } = useMessageNotify();

    //*********************************************************************************************
    //      属性结构管理hook
    //*********************************************************************************************
    //导航树
    const {
      uTreeList,
      getCurrentTree,
      convertToTreeItem
    } = useCommonTree();

    //组织架构树
    let myNavTreeSelectedItem = ref('');
    let myNavTreeRef = ref(null);

    //后台读取数据
    const getCurrentTreeNav = () => {
      getCurrentTree(sysBaseVOAPI.COMPANY_VO_TREE, null);
    }

    //导航树选择事件
    const onNavTreeSelected = () => {
      if (myNavTreeRef.value) {
        let map = convertToTreeItem(myNavTreeSelectedItem.value);
        if (map !== null) {
          queryParam.companyId = map.parentId;
          queryParam.departmentId = map.sonId;

          //console.log(map);
          loadList();
        }
      }
    };

    //*********************************************************************************************
    //      查询模块
    //*********************************************************************************************
    //查询输入参数
    let queryParam = reactive({
      name: '',
      companyId: 0,
      departmentId: 0,
      startDate: '',
      endDate: ''
    });

    //有条件查询
    const queryTable = (s: CQueryParam) => {
      let map = convertToTreeItem(myNavTreeSelectedItem.value);
      if (map) {
        queryParam.companyId = map.parentId;
        queryParam.departmentId = map.sonId;
      }
      //查询时，根据选择树一些参数
      queryParam.name = s.name;    
      queryParam.startDate = s.startDate;
      queryParam.endDate = s.endDate;

      //更新
      loadList();
    };


    //*********************************************************************************************
    //      读取表格数据
    //*********************************************************************************************
    //检索响应数据
    const state = reactive({
      itemData: {
        id: 0,
        nick: 'marry',
        password: '',
        cname: '',
        icon: '',
        sex: 0,
        email: '',
        telephone: '',
        messenger: '',
        positionId: 0,
        departmentId: 0,
        companyId: 0,
        employeeCode: '',
        userStatusId: 0,
        roleId: 0,
        privilege: 0,
        sortCode: '',
        createTime: '',
        createUserId: 0,
        updateTime: '',
        updateUserId: 0
      }
    });


    //查询数据库
    const fetchApi = () => {
      return api.post(sysBaseUrlAPI.SYS_USER_API_PAGE, {
        nick: queryParam.name,
        companyId: queryParam.companyId,
        departmentId: queryParam.departmentId,
        startDate: queryParam.startDate,
        endDate: queryParam.endDate,
        pageNum: dbPagination.value.pageNum,
        pageSize: dbPagination.value.pageSize
      });
    };

    //删除记录
    const deleteApi = (item: ItemType) => {
      return api.post(sysBaseUrlAPI.SYS_USER_API_DELETE, { id: item.id });
    };

    //增加记录
    const confirmAddApi = (item: ItemType) => {
      return api.post(sysBaseUrlAPI.SYS_USER_API_ADD, {
        id: item.id,
        nick: item.nick,
        password: item.password,
        cname: item.cname,
        icon: item.icon,
        sex: item.sex,
        email: item.email,
        telephone: item.telephone,
        messenger: item.menssenger,
        positionId: item.positionId,
        departmentId: item.departmentId,
        companyId: item.companyId,
        employeeCode: item.employeeCode,
        userStatusId: item.userStatusId,
        roleId: item.roleId,
        privilege: item.privilege,
        sortCode: item.sortCode,
        createTime: '',
        createUserId: 0,
        updateTime: '',
        updateUserId: 0
      });
    };

    //修改记录
    const confirmEditApi = (item: ItemType) => {
      return api.post(sysBaseUrlAPI.SYS_USER_API_UPDATE, {
        id: item.id,
        nick: item.nick,
        password: item.password,
        cname: item.cname,
        icon: item.icon,
        sex: item.sex,
        email: item.email,
        telephone: item.telephone,
        messenger: item.messenger,
        positionId: item.positionId,
        departmentId: item.departmentId,
        companyId: item.companyId,
        employeeCode: item.employeeCode,
        userStatusId: item.userStatusId,
        roleId: item.roleId,
        privilege: item.privilege,
        sortCode: item.sortCode,
        createTime: '',
        createUserId: 0,
        updateTime: '',
        updateUserId: 0
      });
    };


    const {
      dbList,
      dbFilterList,
      dbPagination,
      dbCurrentIndex,
      dbStatus,
      getActiveItem,
      filterList,
      loadList,
      addItem,
      editItem,
      deleteItem,
      cancelItem,
      confirmApi
    } = useCommonVisitDatabase(state.itemData, fetchApi, confirmAddApi, confirmEditApi, deleteApi);

    //*********************************************************************************************
    //      目录管理
    //*********************************************************************************************
    const {
      findCatalogLabel,
      findCatalogId
    } = useCatalogTool();

    const {
      sexTypeList,
      statusTypeList,
      positionTypeList,
      departmentTypeList,
      roleList,
      companyList,
      getCatalog,
      removeCatalog
    } = useSysCatalogTbl();

    //*********************************************************************************************
    //      表格
    //*********************************************************************************************
    const columns = [
      {
        name: 'id',
        required: true,
        label: 'ID号',
        align: 'center',
        field: (row:any) => (row.id),
        sortable: true
      },
      { name: 'nick', align: 'center', label: '登录账号', field: 'nick' },
      { name: 'cname', align: 'center', label: '姓名', field: 'cname' },
      { name: 'telephone', align: 'center', label: '电话', field: 'telephone' },
      { name: 'roleId', align: 'center', label: '角色', field: 'roleId' },
      { name: 'userStatusId', align: 'center', label: '状态', field: 'userStatusId' },
      { name: 'operation', align: 'center', label: '操作', field: 'operation' }
    ];

    let tableTitle = ref('用户数据');
    let selectedItems = ref([]);
    let filterText = ref('');
    let myDelDlgRef = ref<DeleteDlgInstance|null>(null);
    let myAddDlgRef = ref<UserDlgInstance|null>(null);
    let myRoleRef = ref<UserSetRoleDlgInstance | null>(null);
    let RoleItem = ref<UserNodeVO>({} as UserNodeVO);
    let deletedIndex = ref(0);

    //检索显示
    const searchTableAry = () => {
      filterList(filterText.value);
    }

    //添加用户
    const addDlgItem = () => {
      if (myAddDlgRef.value) {
        addItem();
        myAddDlgRef.value.show('新建用户信息');
      }
    }

    //编辑用户
    const editDlgItem = (row: number) => {
      if (myAddDlgRef.value) {
        editItem(row);
        myAddDlgRef.value.show('编辑用户信息');
      }
    }

    //删除用户
    const deleteDlgItem = (row: number) => {
      if (myDelDlgRef.value) {
        deletedIndex.value = row;
        myDelDlgRef.value.show('用户信息');
      }
    }

    //更新分页组件
    const refreshTableAry = (pageNum: number) => {
      dbPagination.value.pageNum = pageNum;
      loadList();
    }

    //分配角色
    const assignRole = (id: number, nick: string, rid: number) => {
      if (myRoleRef.value) {
        RoleItem.value.id = id;
        RoleItem.value.nick = nick;
        RoleItem.value.role = findCatalogLabel(roleList.value, rid);
        myRoleRef.value.show('分配用户角色');
      }
    }

    //导出excel
    const exportExcel = () => {
      let workbook = XLSX.utils.table_to_book(document.getElementById('my-xls')); //需要在table上定义一个id
      try {
        XLSX.writeFile(workbook, 'BOX信息.xlsx');
      } catch (e) {
        showMessage('导出失败,失败信息:!');
      }
    }

    //*********************************************************************************************
    //      增加、修改模块
    //*********************************************************************************************
    //取消添加
    const cancelAddDlg = () => {
      //判断是增加还是修改
      if (dbStatus.value === EStatusType.ADD_TYPE) {
        cancelItem(0);
      }
    }

    //新建提交
    const submitAddDlg = (item: UserItem) => {
      confirmApi(item);
      loadList();
    }

    //*********************************************************************************************
    //      删除确认模块
    //*********************************************************************************************
    //提交确认对话框
    const submitDelDlg = (index: number) => {
      deleteItem(index);
    }

    //*********************************************************************************************
    //      分配角色模块
    //*********************************************************************************************
    const cancelAssignRoleDlg = () => {

    }

    const submitAssignRoleDlg = (item: UserNodeVO) => {
      api.post(sysBaseUrlAPI.SYS_USER_API_UPDATE, {
        id: item.id,
        roleId: findCatalogId(roleList.value, item.role)
      }).then((res: any) => {
        loadList();
      });
    }

    //*********************************************************************************************
    //      启动模块
    //*********************************************************************************************
    //初始化
    const init = () => {
      //组织架构
      getCurrentTreeNav();

      //表格数据,无条件查询
      loadList();

      //目录
      getCatalog(sysCatalogType.SEX_TYPE_CODE);
      getCatalog(sysCatalogType.STATUS_TYPE_CODE);
      getCatalog(sysCatalogType.ROLE_CODE);
      getCatalog(sysCatalogType.POSITION_TYPE_CODE);
      getCatalog(sysCatalogType.COMPANY_CODE);
      getCatalog(sysCatalogType.DEPARTMENT_CODE);
    }

    //监视检索框
    watch(filterText, () => {
      searchTableAry();
    });

    //挂载数据
    onMounted(() => {
      init();
    });

    //销毁数据
    onUnmounted(() => {
      removeCatalog(sysCatalogType.SEX_TYPE_CODE);
      removeCatalog(sysCatalogType.STATUS_TYPE_CODE);
      removeCatalog(sysCatalogType.ROLE_CODE);
      removeCatalog(sysCatalogType.POSITION_TYPE_CODE);
      removeCatalog(sysCatalogType.COMPANY_CODE);
      removeCatalog(sysCatalogType.DEPARTMENT_CODE);
    });

    return {
      splitterRatio,

      myNavTreeSelectedItem,
      uTreeList,
      myNavTreeRef,
      getCurrentTreeNav,
      onNavTreeSelected,
      queryTable,

      findCatalogLabel,
      findCatalogId,

      sexTypeList,
      statusTypeList,
      positionTypeList,
      departmentTypeList,
      roleList,
      companyList,

      columns,
      tableTitle,
      selectedItems,
      filterText,
      deletedIndex,
      myDelDlgRef,
      myAddDlgRef,
      myRoleRef,
      RoleItem,
      searchTableAry,
      addDlgItem,
      editDlgItem,
      deleteDlgItem,
      refreshTableAry,
      assignRole,

      dbList,
      dbFilterList,
      dbPagination,
      dbCurrentIndex,
      getActiveItem,

      cancelAddDlg,
      submitAddDlg,
      submitDelDlg,
      cancelAssignRoleDlg,
      submitAssignRoleDlg,

      exportExcel
    }
  }
})

</script>

<style lang="scss" scoped>
.my_input {
  width: 150px;
}
</style>
